﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Device.Location;
using Microsoft.Phone.Net.NetworkInformation;
using System.Windows.Media.Imaging;
using Microsoft.Phone.Controls.Maps;

namespace MOTA_WP
{
    public partial class POIMapPage : PhoneApplicationPage
    {
        GeoCoordinateWatcher _watcher;
        
        protected GeoCoordinate currentPos;
        MapPolygon poly = new MapPolygon();
        MapLayer CenterLayer = new MapLayer();
        MapLayer PushpinLayer = new MapLayer();
        
        public POIMapPage()
        {
            InitializeComponent();
            if (!LBS())
            {
                MessageBox.Show("Can't get the current position.");
                return;
            }
            //add central image to map view
            mainMap.Children.Add(CenterLayer);
            //add central image to map view
            mainMap.Children.Add(PushpinLayer);
            //add the circle to map view
            mainMap.Children.Add(poly);
        }
        /// <summary>
        /// Virtual function for POIMapPage.xaml
        /// 
        /// </summary>
        virtual public void fetchData()
        {
            
        }

        void setMapPos(GeoCoordinate inputPos)
        {
            mainMap.ZoomLevel = 15;
            mainMap.Center = inputPos;
            mainMap.SetView(new Microsoft.Phone.Controls.Maps.LocationRect(currentPos,0.01,0.01));

            //put central image to the central of map
            putCentralImage(currentPos);
            //draw circle
            drawCircle(currentPos, 200);
        }

        bool LBS()
        {
            if (DeviceNetworkInformation.IsNetworkAvailable ||
               DeviceNetworkInformation.IsWiFiEnabled ||
               DeviceNetworkInformation.IsCellularDataRoamingEnabled)
            {
                StartLocationService(GeoPositionAccuracy.Default);
                return true;
            }
            return false;
        }
        protected void putCentralImage(GeoCoordinate pos, Image image = null)
        {
            if (image == null)
            {
                image = new Image();
                image.Source = new BitmapImage(new Uri("images/people.png", UriKind.Relative));
                image.Stretch = Stretch.None;
            }
            CenterLayer.Children.Clear();
            CenterLayer.AddChild(image, pos, new PositionOrigin(0.5, 0.5));
        }

        protected void drawCircle(GeoCoordinate center, double radius)
        {
            //draw circle
            int pointCnt = 36;
            radius *= 0.00001;
            LocationCollection points = new LocationCollection();
            for (double angle = 0; angle < 2 * Math.PI; angle += 2 * Math.PI / pointCnt)
            {
                double x = center.Latitude + Math.Cos(angle) * radius;
                double y = center.Longitude + Math.Sin(angle) * radius;
                
                points.Add(new GeoCoordinate(x, y));
            }
            poly.Locations = points;   //Where points is a List<LocationCollection> object

            //Set the fill and stroke color of circle
            poly.Fill = new SolidColorBrush(Color.FromArgb(50, 110, 160, 216));
            poly.Stroke = new SolidColorBrush(Color.FromArgb(200, 110, 160, 216));
            poly.StrokeThickness = 2;
        }

        protected double distance(GeoCoordinate posSrc, GeoCoordinate posDst)
        {
            return posSrc.GetDistanceTo(posDst);
        }
        #region pushpin_part
        public Pushpin addChild(string Name, string DataContext, GeoCoordinate location)
        {
            Pushpin pushpin = new Pushpin();
            pushpin.Visibility = System.Windows.Visibility.Visible;
            pushpin.DataContext = DataContext;
            pushpin.Name = Name;
            pushpin.Background = new SolidColorBrush(Colors.Blue);
            pushpin.Location = location;
            PushpinLayer.AddChild(pushpin, location);

            return pushpin;
        }
        #endregion

        #region LBS_part
        private void StartLocationService(GeoPositionAccuracy accuracy)
        {
            // Reinitialize the GeoCoordinateWatcher
            
            _watcher = new GeoCoordinateWatcher(accuracy);
            _watcher.MovementThreshold = 20;

            // Add event handlers for StatusChanged and PositionChanged events
            _watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
            _watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);

            // Start data acquisition
            _watcher.Start();
        }
        void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => MyStatusChanged(e));
        }
        /// <summary>
        /// Custom method called from the StatusChanged event handler
        /// </summary>
        /// <param name="e"></param>
        void MyStatusChanged(GeoPositionStatusChangedEventArgs e)
        {
            switch (e.Status)
            {
                case GeoPositionStatus.Disabled:
                    // The location service is disabled or unsupported.
                    // Alert the user
                    
                    break;
                case GeoPositionStatus.Initializing:
                    // The location service is initializing.
                    // Disable the Start Location button
                    
                    break;
                case GeoPositionStatus.NoData:
                    // The location service is working, but it cannot get location data
                    // Alert the user and enable the Stop Location button
                    
                    break;
                case GeoPositionStatus.Ready:
                    // The location service is working and is receiving location data
                    // Show the current position and enable the Stop Location button
                    
                    break;

            }
        }
        /// <summary>
        /// Handler for the PositionChanged event. This invokes MyStatusChanged on the UI thread and
        /// passes the GeoPositionStatusChangedEventArgs
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => MyPositionChanged(e));
        }
        /// <summary>
        /// Custom method called from the PositionChanged event handler
        /// </summary>
        /// <param name="e"></param>
        void MyPositionChanged(GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            currentPos = e.Position.Location;
            //MessageBox.Show(e.Position.Location.ToString());
            setMapPos(currentPos);
        }
        #endregion
    }
}